﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using WPFCABShell.Shell.Interface;
using WPFCABShell.Shell.Interface.Services.Command;
using WPFCABShell.Shell.Interface.Services.Menu;
using Microsoft.Practices.ObjectBuilder;
using CAB = Microsoft.Practices.CompositeUI.Commands;
using WPF = System.Windows.Input;
using Kent.Boogaart.HelperTrinity;
using Microsoft.Practices.CompositeUI.Commands;

namespace MenuDemo
{
	public sealed class MenuDemoPresenter : Presenter<IMenuDemoView>, INotifyPropertyChanged
	{
		private readonly ICommandService _commandService;
		private readonly IMenuService _menuService;
		private const string _topLevelMenuItemSiteName = "site://Menu/MenuDemo/TopLevelSite";

		public event PropertyChangedEventHandler PropertyChanged;

		public MenuDemoPresenter([Dependency] ICommandService commandService, [Dependency] IMenuService menuService)
		{
			_commandService = commandService;
			_menuService = menuService;
		}

		#region Example 1

		private Example1Step _example1CurrentStep;
		private IMenuItem _topLevelMenuItem;
		private IMenuItem _childMenuItem;

		public Example1Step Example1CurrentStep
		{
			get
			{
				return _example1CurrentStep;
			}
			private set
			{
				if (_example1CurrentStep != value)
				{
					_example1CurrentStep = value;
					OnPropertyChanged("Example1CurrentStep");
				}
			}
		}

		public void Example1AddTopLevelMenuItem()
		{
			ICommand command = _commandService.CreateCommand("Top Level Item", null);
			_topLevelMenuItem = _menuService.Add(ExtensionSites.Menu.Name, command, ExtensionSites.Menu.File.GroupIndex, ExtensionSites.Menu.File.Index + 1, _topLevelMenuItemSiteName);

			Example1CurrentStep = Example1Step.AddedTopLevelMenuItem;
		}

		public void Example1AddChildMenuItem()
		{
			ICommand childCommand = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Child Menu Item", null);
			_childMenuItem = _menuService.Add(_topLevelMenuItemSiteName, childCommand, null, null, null);

			Example1CurrentStep = Example1Step.AddedChildMenuItem;
		}

		public void Example1RemoveChildMenuItem()
		{
			_menuService.Remove(_childMenuItem);

			Example1CurrentStep = Example1Step.AddedTopLevelMenuItem;
		}

		public void Example1RemoveTopLevelMenuItem()
		{
			_menuService.Remove(_topLevelMenuItem);

			Example1CurrentStep = Example1Step.Start;
		}

		public enum Example1Step
		{
			Start,
			AddedTopLevelMenuItem,
			AddedChildMenuItem
		}

		#endregion

		#region Example 2

		private IMenuItem _menuItemWithImage;
		private IMenuItem _menuItemForChecking;

		public bool Example2CanAddMenuItemWithImage()
		{
			return _menuItemWithImage == null;
		}

		public void Example2AddMenuItemWithImage()
		{
			ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Menu Item With Image", View.MenuItemImage);
			_menuItemWithImage = _menuService.Add(ExtensionSites.Menu.File.Name, command, null, null, null);
		}

		public bool Example2CanAddCheckableMenuItem()
		{
			return _menuItemForChecking == null;
		}

		public void Example2AddCheckableMenuItem()
		{
			ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Menu Item With CheckBox", null);
			_menuItemForChecking = _menuService.Add(ExtensionSites.Menu.File.Name, command, null, null, null);
		}

		public bool Example2CanCheckUncheckMenuItem()
		{
			return _menuItemForChecking != null;
		}

		public void Example2CheckUncheckMenuItem()
		{
			Debug.Assert(_menuItemForChecking != null);
			_menuItemForChecking.IsChecked = !_menuItemForChecking.IsChecked;
		}

		public bool Example2CanCleanUp()
		{
			return (_menuItemWithImage != null) || (_menuItemForChecking != null);
		}

		public void Example2CleanUp()
		{
			if (_menuItemWithImage != null)
			{
				_menuService.Remove(_menuItemWithImage);
			}

			if (_menuItemForChecking != null)
			{
				_menuService.Remove(_menuItemForChecking);
			}

			_menuItemWithImage = null;
			_menuItemForChecking = null;
		}

		#endregion

		#region Example 3

		private IMenuItem _sortedMenuItem;
		private IMenuItem _groupedMenuItem;
		private IMenuItem _groupedAndSortedMenuItem1;
		private IMenuItem _groupedAndSortedMenuItem2;

		public bool Example3CanAddSortedMenuItem()
		{
			return _sortedMenuItem == null;
		}

		public void Example3AddSortedMenuItem()
		{
			ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Sorted Menu Item", null);
			_sortedMenuItem = _menuService.Add(ExtensionSites.Menu.Edit.Name, command, ExtensionSites.Menu.Edit.Copy.GroupIndex, ExtensionSites.Menu.Edit.Copy.Index + 1, null);
		}

		public bool Example3CanAddGroupedMenuItem()
		{
			return _groupedMenuItem == null;
		}

		public void Example3AddGroupedMenuItem()
		{
			ICommand command = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Grouped Menu Item", null);
			_groupedMenuItem = _menuService.Add(ExtensionSites.Menu.Edit.Name, command, ExtensionSites.Menu.Edit.Copy.GroupIndex + 1, 0, null);
		}

		public bool Example3CanAddGroupedAndSortedMenuItems()
		{
			return _groupedMenuItem != null && _groupedAndSortedMenuItem1 == null;
		}

		public void Example3AddGroupedAndSortedMenuItems()
		{
			ICommand command1 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Grouped and Sorted Menu Item 1", null);
			ICommand command2 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Grouped and Sorted Menu Item 2", null);
			_groupedAndSortedMenuItem1 = _menuService.Add(ExtensionSites.Menu.Edit.Name, command1, ExtensionSites.Menu.Edit.Copy.GroupIndex + 1, 1, null);
			_groupedAndSortedMenuItem2 = _menuService.Add(ExtensionSites.Menu.Edit.Name, command2, ExtensionSites.Menu.Edit.Copy.GroupIndex + 1, -1, null);
		}

		public bool Example3CanCleanUp()
		{
			return _sortedMenuItem != null || _groupedMenuItem != null || _groupedAndSortedMenuItem1 != null;
		}

		public void Example3CleanUp()
		{
			if (_sortedMenuItem != null)
			{
				_menuService.Remove(_sortedMenuItem);
				_sortedMenuItem = null;
			}

			if (_groupedMenuItem != null)
			{
				_menuService.Remove(_groupedMenuItem);
				_groupedMenuItem = null;
			}

			if (_groupedAndSortedMenuItem1 != null)
			{
				_menuService.Remove(_groupedAndSortedMenuItem1);
				_menuService.Remove(_groupedAndSortedMenuItem2);
				_groupedAndSortedMenuItem1 = null;
				_groupedAndSortedMenuItem2 = null;
			}
		}

		#endregion

		#region Example 4

		private IMenuItem _parentMenuItem;
		private IMenuItem _childMenuItem1;
		private IMenuItem _childMenuItem2;

		public bool Example4CanAddParentMenuItem()
		{
			return _parentMenuItem == null;
		}

		public void Example4AddParentMenuItem()
		{
			ICommand command = _commandService.CreateCommand("Parent Menu Item", null);
			_parentMenuItem = _menuService.Add(ExtensionSites.Menu.File.Name, command, null, null, "SiteName");
		}

		public bool Example4CanAddChildMenuItems()
		{
			return _parentMenuItem != null && _childMenuItem1 == null;
		}

		public void Example4AddChildMenuItems()
		{
			ICommand command1 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Child Menu Item 1", null);
			ICommand command2 = _commandService.CreateCommand(WorkItem.Commands["ChildMenuItem"], "Child Menu Item 2", null);
			_childMenuItem1 = _menuService.Add("SiteName", command1, null, null, null);
			_childMenuItem2 = _menuService.Add("SiteName", command2, null, null, null);
		}

		public bool Example4CanCleanUp()
		{
			return _parentMenuItem != null;
		}

		public void Example4CleanUp()
		{
			_menuService.Remove(_parentMenuItem);
			_parentMenuItem = null;
			_childMenuItem1 = null;
			_childMenuItem2 = null;
		}

		#endregion

		[CommandHandler("ChildMenuItem")]
		public void ChildMenuItem(object sender, EventArgs e)
		{
			View.ShowChildMenuItemClicked();
		}

		private void OnPropertyChanged(string propertyName)
		{
			EventHelper.Raise(PropertyChanged, this, new PropertyChangedEventArgs(propertyName));
		}
	}
}
